package org.zfes.snowy.auth.biz;


import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.zfes.snowy.auth.biz.model.AuthPermission;
import org.zfes.snowy.auth.biz.service.IAuthPermissionService;
import org.zfes.snowy.auth.biz.service.impl.AuthPermissionServiceImpl;
import org.zfes.snowy.core.idcenter.IDGenerator;
import org.zfes.snowy.core.util.AppCtxUtil;
import org.zfes.snowy.core.util.ZAlert;
import org.zfes.snowy.core.util.ZClassUtil;
import org.zfes.snowy.core.util.ZObjectUtil;



@Component
public class PermScan {
	
	
	
	private IAuthPermissionService authPermissionService=AppCtxUtil.getBean(AuthPermissionServiceImpl.class);
	
	public void scanPacgeToloadPermis(String packageName,Long appId,Long mid) {
		Set<Class<?>> calssSet=scanAllController( packageName);
		if(ZObjectUtil.isEmpty(calssSet)){
			ZAlert.Error("未扫描到任何类");
		}
		List<AuthPermission> permissList=new ArrayList<>();
		for(Class<?> calzz:calssSet){
			Method[] methods=calzz.getDeclaredMethods();
			String clazzUrl="";
			if(calzz.isAnnotationPresent(RequestMapping.class)){
				RequestMapping rm=calzz.getAnnotation(RequestMapping.class);
				String[] clazzUrlArray=rm.value();
				clazzUrl=clazzUrlArray[0];
				
			}
			if(methods==null||methods.length==0){
				continue;
			}
			for(Method method:methods){
				String url="";
				if(method.isAnnotationPresent(RequestMapping.class)){
					RequestMapping mrp=method.getAnnotation(RequestMapping.class);
					String[] methodUrl=mrp.value();
					System.out.println(clazzUrl+methodUrl[0]);//permission--URL
					url=clazzUrl+methodUrl[0];
				}
				if(method.isAnnotationPresent(RequiresPermissions.class)){
					Annotation rp=method.getAnnotation(RequiresPermissions.class);
					String[] methodRPerms=((RequiresPermissions) rp).value();//permission--Code
					String methodname=((RequiresPermissions) rp).desc();
					if(methodRPerms!=null&&methodRPerms.length>1){//多个 pemis
						for(String str:methodRPerms){
							AuthPermission perms=new AuthPermission();
							perms.setId(IDGenerator.genLongId());
							perms.setUrl(url);
							perms.setEnabled(true);
							perms.setName(methodname);
							perms.setPermCode(str);
							perms.setDescription(methodname);
							perms.setAppKey("APP_ROOT");
							perms.setType("p");
							perms.setModuleId(mid);
							permissList.add(perms);
						
						}
					}else if(methodRPerms!=null&&methodRPerms.length==1){
						AuthPermission perms=new AuthPermission();
						perms.setId(IDGenerator.genLongId());
						perms.setUrl(url);
						perms.setEnabled(true);
						perms.setName(methodname);
						perms.setPermCode(methodRPerms[0]);
						perms.setDescription(methodname);
						perms.setAppKey("APP_ROOT");
						perms.setType("p");
						perms.setModuleId(mid);
						permissList.add(perms);
						
					}else if(methodRPerms==null||methodRPerms.length==0){
						AuthPermission perms=new AuthPermission();
						perms.setId(IDGenerator.genLongId());
						perms.setUrl(url);
						perms.setEnabled(true);
						perms.setName(methodname);
						perms.setPermCode("");
						perms.setDescription(methodname);
						perms.setAppKey("APP_ROOT");
						perms.setType("p");
						perms.setModuleId(mid);
						permissList.add(perms);
					}
				}
			}
			int cpunt=0;
			for(AuthPermission p :permissList){
				Optional<AuthPermission> permission=authPermissionService.loadAuthPermissionByCode(p.getPermCode());
				if(!permission.isPresent()){
					authPermissionService.createAuthPermission(p);
					cpunt++;
				}
			}
			System.out.println("共扫描"+cpunt+"个权限");
			
		}
	}
	
	public static Set<Class<?>> scanAllController(String basePakage){
		if(basePakage==null||basePakage.isEmpty()){
			return null;
		}
		Set<Class<?>> calssSet=ZClassUtil.scanClass(basePakage, Controller.class);
		return calssSet;
	}
	
}
